package com.party.mobile.web.aop;

import com.party.common.utils.DateUtils;
import com.party.core.model.collect.SystemModuleCollect;
import com.party.core.model.collect.SystemPlatformCollect;
import com.party.core.model.system.TargetType;
import com.party.core.service.collect.biz.SystemCollectBizService;
import com.party.mobile.web.annotation.VisitCollect;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;
import java.util.Date;

/**
 * @Description:
 * @Author: yangshoukun
 * @Date: 2018/6/21 11:09
 */
@Component
@Aspect
public class VisitCollectAop {

    private static Logger logger = LoggerFactory.getLogger(VisitCollectAop.class);

    private static final String COOKIE_PLATFORM = "txz_visit_collect_platform";

    private static String COOKIE_MODULE = "txz_visit_collect_module_";

    @Autowired
    private SystemCollectBizService systemCollectBizService;

    @Around("@annotation(com.party.mobile.web.annotation.VisitCollect)")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        VisitCollect annotation = method.getAnnotation(VisitCollect.class);

        if (null != annotation) {
            VisitCollect.SCOPE[] scopes = annotation.scope();
            VisitCollect.CONTENT[] contents = annotation.content();
            TargetType module = annotation.module();
            try {
                Date now = new Date();
                ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
                HttpServletRequest request = requestAttributes.getRequest();
                HttpServletResponse response = requestAttributes.getResponse();

                finish:
                for (VisitCollect.SCOPE scope : scopes) {
                    if (scope.getCode().equals(VisitCollect.SCOPE.MODULE.getCode())) {
                        // 模块统计
                        if (null == module) {
                            logger.error("模块统计的模块参数不能为空, method = {}", method.getName());
                            break finish;
                        }
                        count(module, now, contents, request, response);
                    }
                    if (scope.getCode().equals(VisitCollect.SCOPE.PLATFORM.getCode())) {
                        // 平台统计
                        count(null, now, contents, request, response);
                    }
                }
            } catch (Exception e) {
                logger.error("的pv,uv统计异常", e);
            }
        }

        Object result = joinPoint.proceed();
        return result;
    }

    private void count(TargetType module, Date now, VisitCollect.CONTENT[] contents, HttpServletRequest request, HttpServletResponse response) {
        if (null == module) {
            // 平台统计
            SystemPlatformCollect platformCollect = new SystemPlatformCollect(now, null, null);
            platformCollect.setUpdateDate(now);
            for (VisitCollect.CONTENT content : contents) {
                if (content.getCode().equals(VisitCollect.CONTENT.PV.getCode())) {
                    platformCollect.setPvNum(1L);
                }
                if (content.getCode().equals(VisitCollect.CONTENT.UV.getCode())) {
                    if (isAdd(COOKIE_PLATFORM, now, request, response)) {
                        platformCollect.setUvNum(1L);
                    }
                }
            }
            systemCollectBizService.countPlatform(platformCollect);
        } else {
            // 模块统计
            SystemModuleCollect moduleCollect = new SystemModuleCollect(module.getCode(), now, null, null);
            moduleCollect.setUpdateDate(now);
            for (VisitCollect.CONTENT content : contents) {
                if (content.getCode().equals(VisitCollect.CONTENT.PV.getCode())) {
                    moduleCollect.setPvNum(1L);
                }
                if (content.getCode().equals(VisitCollect.CONTENT.UV.getCode())) {
                    if (isAdd(COOKIE_MODULE + module.getCode(), now, request, response)) {
                        moduleCollect.setUvNum(1L);
                    }
                }
            }
            systemCollectBizService.countModule(moduleCollect);
        }
    }

    private boolean isAdd(String name, Date now, HttpServletRequest request, HttpServletResponse response) {
        Cookie[] cookies = request.getCookies();
        boolean find = false;
        if (null != cookies) {
            for (Cookie cookie : cookies) {
                if (cookie.getName().equals(name)) {
                    find = true;
                    break;
                }
            }
        }
        if (!find) {
            Cookie cookie = new Cookie(name, name);
            Date tonight = DateUtils.getTodayNight();
            long time = (tonight.getTime() - now.getTime()) / DateUtils.MILLIS_PER_SECOND;
            cookie.setMaxAge((int) time);
            cookie.setPath("/");
            response.addCookie(cookie);
        }
        return !find;
    }
}
